﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Threading;
using DownloadInterface.DownloadError;


namespace DownloadInterface
{
    public class DownloadController
    {
        IDownloadManage _downloadManager;

        IFileManage _fileManageer;

        IUserInterface _userInterface;

        public DownloadController(IDownloadManage downloadManager,
                                    IFileManage fileManager,
                                    IUserInterface userInterface)
        {
            this._downloadManager = downloadManager;
            
            this._fileManageer = fileManager;
        
            this._userInterface = userInterface;

            this._userInterface.OperateDownloadTask += new operateDowloadTask(userInterface_OperateDownloadTask);

            this._userInterface.OperateDownloadFile += new operateDownloadedFile(userInterface_OperateDownloadFile);

            this._userInterface.DownloadCompleted += new DownloadCompletedEventHandler(_userInterface_DownloadCompleted);

            this._userInterface.CategoryChanged += new CategoryChangedEventHandler(_userInterface_CategoryChanged);

            this._userInterface.WindowClose += new WindowCloseEventHandler(_userInterface_WindowClose);

            this._downloadManager.DownloadCompleted +=new DownloadCompletedEventHandler(_userInterface.handleDownloadCompleted);

            this._downloadManager.DownloadErrorEvent += new DownloadErrorEventHandler(_downloadManager_DownloadErrorEvent);

            this._fileManageer.DownloadErrorEvent += new DownloadErrorEventHandler(_downloadManager_DownloadErrorEvent); 
            Initializer();
        }

        void _userInterface_WindowClose()
        {
            this._downloadManager.SaveState();
        }

        void _downloadManager_DownloadErrorEvent(ErrorCode errorCode)
        {
            string errorDiscription = ErrorCodeInterpreter.GetErrorDiscription(errorCode);
            this._userInterface.displayDownloadError(errorDiscription);
        }

        void _userInterface_DownloadCompleted(DownloadTask finishedTask)
        {
            if (this._fileManageer.addFile(finishedTask))
            {
                    this._downloadManager.operateDownload(finishedTask, DownloadTaskOperation.DOWNLOAD_CANCEL);
            }
            else
            {
                throw (new Exception("save file error"));
            }
        }

        private void Initializer()
        {
            this._userInterface.displayDownloadTaskList(
                this._downloadManager.getDownloadList());
            this._userInterface.displayDownloadedFileCategory(
                this._fileManageer.getFileCategoryList());
        }

        void _userInterface_CategoryChanged()
        {
            FileCategory currentCategory = this._userInterface.getCurrentCategory();
            this._userInterface.displayDownloadedFileList(this._fileManageer.getDownloadedFileList(currentCategory));
        }

        void userInterface_OperateDownloadFile(DownloadedFileOperation operation)
        {
            switch (operation)
            {
                case DownloadedFileOperation.FILE_DELETE:
                    DownloadedFile file = this._userInterface.getCurrentFile();
                    FileCategory category = this._userInterface.getCurrentCategory();
                    this._fileManageer.deleteFile(category,file);
                    break;
                default: throw new NotImplementedException();
            }
        }

        void userInterface_OperateDownloadTask(DownloadTaskOperation operation)
        {
            DownloadTask task = null;
            if (operation == DownloadTaskOperation.DOWNLOAD_NEW)
            {
                task = _userInterface.getNewDownloadTask();
                _fileManageer.setFileType(task);
                this._downloadManager.startDownload(task);
            }
            else
            {
                task = this._userInterface.getCurrentTask();
                this._downloadManager.operateDownload(task,operation);
            }
        }
    }
}
